#include <am.h>
#include <klib.h>
#include <klib-macros.h>
#include <riscv/riscv.h>
#include "include/npc.h"

// extern告诉编译器，这个符号来自外部，需要在链接时才能解析
// 链接脚本中可以定义符号到符号表，其他目标文件也能生成符号到符号表
// 最终extern的符号，在符号表中被解析
extern char _pmem_start; 
#define PMEM_SIZE (128 * 1024 * 1024)
#define PMEM_END  ((uintptr_t)&_pmem_start + PMEM_SIZE)

extern char _heap_bottom,_heap_top;
Area heap;

#ifndef MAINARGS
#define MAINARGS ""
#endif
static const char mainargs[] = MAINARGS;

void putch(char ch) {
    // 每次发送前，需要给UART寄存器设置参数（此处仅设置波特率即可）
	char lsr = 0x00;
	while((lsr & 0x20) == 0x0){
		lsr = inb(UART_LSR);
	}
    outb(UART_LCR_DIV, 0x80); // 打开第7个bit（除数访问位，注意是从0开始）
    outb(UART_DIV_H, 0x00);  // 任意设置除数
    outb(UART_DIV_L, 0x05);  // 任意设置除数
    outb(UART_LCR_DIV, 0x0); // 关闭第7bit（除数访问位）
	outb(UART_TX,ch);
}

void halt(int code) {
	npc_trap(code);

	while (1);
}


extern uint32_t _data_start, _data_end, _bss_start, _bss_end, _data_load, _bss_load;
void bootloader(){
    uint32_t* src = &_data_load;
    uint32_t* ptr = &_data_start;
    // src++,ptr++;
    while(ptr < &_data_end ) *ptr++ = *src++;


    src = &_bss_load;
    ptr = &_bss_start;
    // src++,ptr++;
    while(ptr < &_bss_end ) *ptr++ = *src++;

    // src = &_data_extra_load;
    // ptr = &__fsymtab_start;
    // // src++,ptr++;
    // while(ptr < &__am_apps_data_end ) *ptr++ = *src++;

    // src = &_bss_extra_load;
    // ptr = &__am_apps_bss_start;
    // // src++,ptr++;
    // while(ptr < &__am_apps_bss_end ) *ptr++ = *src++;
}

void bootloader_secondary(){
    
}

int main(const char *args);
void _trm_init() {
    // printf("START BOOT\n");
    // bootloader();
    // printf("END BOOT\n");
    // heap = RANGE(&_heap_bottom, &_heap_top);
	int ret = main(mainargs);
	halt(ret);
}
